#ifndef CAMERA_MANIPULATOR_INTERSECTION
#define CAMERA_MANIPULATOR_INTERSECTION 1
#include <Define.h>

#include <string>

#include <osg/Node>
#include <osg/Geode>
#include <osg/AutoTransform>
#include <osg/Geometry>
#include <osgText/Text>
#include <osg/ShapeDrawable>
#include <osg/Shape>
#include <osg/MatrixTransform>
#include <osgGA/CameraManipulator>

class OSG_EDITOR_DLL CameraManipulatorIntersection :public osgGA::CameraManipulator
{
public:
    CameraManipulatorIntersection();
    virtual ~CameraManipulatorIntersection();


    virtual void setByMatrix(const osg::Matrixd& matrix) ;

    virtual void setByInverseMatrix(const osg::Matrixd& matrix) ;

    virtual osg::Matrixd getMatrix() const ;

    virtual osg::Matrixd getInverseMatrix() const ;

    virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
    virtual void home( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us );
    virtual void computeHomePosition(const osg::Camera *camera = NULL, bool useBoundingBox = false);

    virtual void setNode(osg::Node* node);
    virtual const osg::Node* getNode() const;
    virtual osg::Node* getNode();

protected:

    virtual bool handleFrame( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us );
    virtual bool handleResize( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us );
    virtual bool handleMouseMove( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us );
    virtual bool handleMouseDrag( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us );
    virtual bool handleMousePush( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us );
    virtual bool handleMouseRelease( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us );
    virtual bool handleKeyDown( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us );
    virtual bool handleKeyUp( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us );
    virtual bool handleMouseWheel( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us );
    virtual bool handleMouseDeltaMovement( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us );

    virtual bool handleMouseDragLeft(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
    virtual bool handleMouseDragMiddle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
    virtual bool handleMousePushIntersection( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us );
    virtual bool handleMouseReleaseIntersection(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);

    void zoom( const float interval);
    void pan( const float dx, const float dy );

    void rotateTrackball( const float px0, const float py0,const float px1, const float py1 );
    void trackball( osg::Vec3d& axis, float& angle, float p1x, float p1y, float p2x, float p2y );
    float tb_project_to_sphere( float r, float x, float y );

    void createInsertPoint(osg::Vec3d& pos);

    osg::Vec3d _center;
    osg::Quat  _rotation;
    double     _distance;

    osg::Vec3d _insert_center;
    osg::Matrix _rotation_matrix;
    osg::Matrix _center_matrix;

    int _pushed_mouse_button_mask;//-1 when release
    float _last_x;
    float _last_y;

    osg::ref_ptr< osg::Node> _insert_point;

    osg::ref_ptr< osg::Node > _node;
};



#endif  // !CAMERA_MANIPULATOR_INTERSECTION
